home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
turbo_tk.arc
/
MENUTTT.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1988-02-01
|
19KB
|
491 lines
{$S-,R-,V-,D-,T-}
{\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\}
{ TechnoJocks Turbo Toolkit v4.00 Released: Feb 1, 1988 }
{ }
{ Module: MenuTTT -- menu displaying procedues }
{ }
{ Copyright R. D. Ainsbury (c) 1986 }
{\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\}
Unit MenuTTT;
interface
Uses CRT, FastTTT, DOS, WinTTT, KeyTTT;
const
Max_Choices = 30;
type
Menu_record = record
Heading1 : string; { '' for no heading}
Heading2 : string;
Topic : array[1..Max_Choices] of string;
TotalPicks : integer;
PicksPerLine : byte;
AddPrefix : byte; {0 no, 1 No.'s, 2 Lets}
TopLeftXY : array[1..2] of byte; {X,Y}
Boxtype : byte; {0,1,2,3, >3}
Colors : array[1..5] of byte; {HF,HB,LF,LB,Box}
Margins : byte;
AllowEsc : boolean; {true if Esc will exit}
end;
Procedure DisplayMenu(MenuDef: Menu_record;
Window:Boolean;
var Choice,Errorcode : integer);
Implementation
Procedure DisplayMenu(MenuDef: Menu_record;
Window:Boolean;
var Choice,Errorcode : integer);
Const
Alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
Numbers = '123456789';
var
I,J,X2,Y2,heading_Lines : integer;
TextWidth : byte;
Function Int_to_Str(Number:Integer):string;
var Temp : string;
begin
Str(Number,temp);
Int_to_Str := temp;
end;
Function Str_to_Int(Str:string):integer;
var temp,code : integer;
begin
If length(Str) = 0 then
Str_to_Int := 0
else
begin
val(Str,temp,code);
if code = 0 then
Str_to_Int := temp
else
Str_to_Int := 0;
end;
end;
Procedure GetDimensions;
var Fullwidth,MaxWidth: integer;
Procedure Validate_Prefix; { 0 no prefix }
begin { 1 numbers prefix}
with MenuDef do { 2 letters prefix}
begin { 3 function key prefix}
If PicksPerLine < 1 then PicksPerLine := 1;
If (TotalPicks = 10) and (AddPrefix = 1) then
AddPrefix := 3;
If (TotalPicks > 10) and (AddPrefix in [1,3]) then
AddPrefix := 2;
If (Addprefix > 3) or (TotalPicks > 26) or (Addprefix < 0) then
Addprefix := 0;
end; {do}
end; {Validate_Prefix}
Procedure Add_Prefix;
var I : integer;
begin
With MenuDef do
begin
Case AddPrefix of
1 : for I := 1 to TotalPicks do
Topic[I] := int_to_str(I) + ' ' + Topic[I];
2 : for I := 1 to TotalPicks do
Topic[I] := Copy(Alphabet,I,1) + ' ' + Topic[I];
3 : If TotalPicks < 10 then
for I := 1 to TotalPicks do
Topic[I] := 'F'+Int_to_Str(I) + ' ' + Topic[I]
else
begin {add extra space for F10 }
for I := 1 to 9 do
Topic[I] := 'F'+Int_to_Str(I) + ' ' + Topic[I];
Topic[10] := 'F10 '+ Topic[10];
end;
end; {case}
end; {do}
end; {proc Add_Prefix}
Procedure Find_Longest_Topic;
var
I,J: integer;
begin
with MenuDef do
begin
Textwidth := 0;
For I := 1 to TotalPicks do
If length(Topic[I]) > TextWidth then
Textwidth := length(Topic[I]); {find the longest text}
end; {with}
end; {Proc Find_Widest_Line}
Procedure Adjust_Text_Width(Len:integer);
var I,J : integer;
begin
With MenuDef do
begin
For I := 1 to TotalPicks do
If length(Topic[I]) > Len then {reduce it}
Delete(Topic[I],succ(Len),length(Topic[I]) - Len)
else {expand it}
For J := length(Topic[I]) + 1 to Textwidth do
Topic[I] := Topic[I] + ' ';
end; {do}
end;
Procedure Determine_MaxWidth;
{findout the max internal menu space - MaxWidth}
begin
with MenuDef do
begin
If margins < 0 then Margins := 0;
If not (BoxType in [0..9]) then
BoxType := 0;
MaxWidth := 80 - 2*Margins - 1; {-1 for arrow symbol to left of pick}
Case BoxType of
1..4 : MaxWidth := MaxWidth - 2; {box sides}
5 : MaxWidth := pred(MaxWidth); {box shadow}
6..9 : MaxWidth := MaxWidth - 3; {box sides and shadow}
end;
end; {with}
end;
Procedure Validate_PicksPerLine;
begin
With MenuDef do
begin
If succ(TextWidth)*PicksPerLine <= MaxWidth then
exit; {no adjustment necessary, everything fits}
If (TextWidth-2)*PicksPerLine <= Maxwidth then
TextWidth := pred(MaxWidth div PicksperLine)
else
begin
While succ(TextWidth)*PicksPerLine > MaxWidth do
PicksPerLine := pred(PicksPerLine);
If PicksPerLine = 0 then
begin
TextWidth := pred(MaxWidth);
PicksPerLine := 1;
end;
end;
end; {with}
end; {Proc Validate_PicksPerLine}
Procedure Determine_X_Dimensions;
{Checks to see if the menu will fit, if it won't it changes something!}
begin
With MenuDef do
begin
Fullwidth := succ(Textwidth)*PicksPerLine + 2*Margins;
Case BoxType of
1..4 : FullWidth := FullWidth + 2; {box sides}
5 : FullWidth := succ(FullWidth); {box shadow}
6..9 : FullWidth := FullWidth + 3; {box sides and shadow}
end; {Case}
If TopleftXY[1] < 1 then
TopleftXY[1] := (80 - Fullwidth) div 2;
If TopLeftXY[1] + Fullwidth < 80 then
X2 := TopleftXY[1] + Fullwidth
else
begin
X2 := 80;
TopLeftXY[1] := 80 - Fullwidth + 1;
end;
end; {with}
end; {Proc Determine_X_Dimensions}
Procedure Determine_Y_Dimensions;
var
BoxLines,
TopicLines,
FullDepth : integer;
begin
With MenuDef do
begin
TopicLines := TotalPicks div PicksPerLine; {no of full rows of picks}
If TotalPicks mod PicksPerLine > 0 then {+1 if partial row of picks}
TopicLines := succ(TopicLines);
Case BoxType of
0 : Boxlines := 0;
1..5 : BoxLines := 2; {box sides}
6..9: BoxLines := 3; {box sides and shadow}
end;
Heading_Lines := 0;
If length(Heading1) > 0 then
Heading_Lines := succ(Heading_Lines);
If length(Heading2) > 0 then
Heading_Lines := succ(Heading_Lines);
If Heading_Lines > 0 then {add a line for a gap}
Heading_Lines := succ(Heading_Lines); {gap above topics}
If BoxType = 5 then
Heading_Lines := succ(Heading_Lines);
Fulldepth := BoxLines+TopicLines+Heading_Lines;
If Heading_Lines > 0 then
Fulldepth := succ(Fulldepth); {+1 gap below topics if headings}
If FullDepth > 25 then {if it doesn't fit, drop off topics}
begin
If Heading_Lines > 0 then
TotalPicks := (25 - BoxLines -Heading_Lines-1)*PicksPerLine
else
TotalPicks := (25 - BoxLines - Heading_Lines)*PicksPerLine;
FullDepth := 25;
end;
If TopLeftXY[2] <= 0 then
TopLeftXY[2] := (25 - Fulldepth) div 2 +1;
If TopLeftXY[2] + Fulldepth - 1 <= 25 then
begin
If BoxType > 4 then {shadow}
Y2 := TopleftXY[2] + pred(Fulldepth) - 1
else
Y2 := TopleftXY[2] + pred(Fulldepth);
end
else
begin
If BoxType > 4 then {shadow}
Y2 := 24
else
Y2 := 25;
TopLeftXY[2] := 25 - Fulldepth + 1;
end;
end; {do}
end; {Proc Determine_Y_Dimensions}
begin {Get_Dimensions}
Validate_Prefix;
Add_Prefix;
Find_Longest_Topic;
Determine_MaxWidth;
Validate_PicksPerLine;
Adjust_Text_Width(TextWidth);
Determine_X_Dimensions;
Determine_Y_Dimensions;
end; {proc GetDimensions}
Procedure Write_Text(Item:integer;Highlight:boolean);
Var X,Y,A:integer;
begin
With MenuDEf do
begin
A := Item mod PicksPerLine;
Y := Item div PicksPerLine +TopleftXY[2] + ord(A <> 0);
Y := Y + Heading_lines - ord(Boxtype = 0);
If A = 0 then A := PicksPerLine; {A is now the no of picks from left}
X := (A - 1)*(TextWidth + 1)+Margins+
TopleftXY[1]+1 + ord(BoxType > 0); {title width + 1 for a space}
If Highlight then
begin
WriteAt(X,Y,colors[1],colors[2],Topic[item]);
WriteAT(pred(X),Y,colors[5],colors[2],chr(16)); {write arrow head}
end
else
begin
WriteAT(X,Y,colors[3],colors[4],Topic[item]);
WriteAT(pred(X),Y,colors[3],colors[4],' '); {remove arrow head}
end;
end; {do}
end; {Proc Write_Text}
Procedure CreateMenu;
var I : integer;
begin
with MenuDef do
begin
If Window then
MkWin(TopleftXY[1],TopLeftXY[2],X2,Y2+1,colors[3],colors[4],0)
else
ClearText(TopleftXY[1],TopLeftXY[2],X2,Y2,colors[3],colors[4]);
If (BoxType in [5..9]) and (TopleftXY[1] > 1) then {draw a shadow}
begin
For I := TopleftXY[2]+1 to Y2+1 do
WriteAt(pred(TopLeftXY[1]),I,colors[3],black,' ');
WriteAt(TopLeftXY[1],succ(Y2),colors[3],black,
replicate(X2-succ(TopLeftXY[1]),' '));
end;
Case Boxtype of
1..4: Box(TopLeftXY[1],TopLeftXY[2],X2,Y2,colors[5],colors[4],Boxtype);
5 : begin
WriteAT(TopleftXY[1],TopleftXY[2],colors[5],colors[4],
replicate(succ(X2 - TopleftXY[1]),chr(223)));
WriteAT(TopleftXY[1],TopleftXY[2]+Heading_Lines-1,colors[5],colors[4],
replicate(succ(X2 - TopleftXY[1]),chr(196)));
end;
6..9:Box(TopLeftXY[1],TopLeftXY[2],X2,Y2,colors[5],colors[4],Boxtype-5);
end; {case}
If length(Heading1) > 0 then
WriteBetween(TopleftXY[1],X2,
TopLeftXY[2]+ord(BoxType > 0),
colors[1],colors[4],Heading1);
If length(Heading2) > 0 then
WriteBetween(TopleftXY[1],X2,
TopLeftXY[2]+ord(BoxType > 0)+ord(Heading_Lines <> 2),
colors[1],colors[4],Heading2);
For I := 1 to TotalPicks do
Write_Text(I,false);
Write_Text(Choice,True); {Highlight Default}
end; {do}
end; {Proc CreateMenu}
Procedure Process_Keystrokes;
var
Selected: Boolean;
CHpk:char;
Oldchoice:integer;
begin
Selected := false;
With MenuDef do
begin
Repeat
Chpk := GetKey;
Case CHpk of
#208 : begin {Cursor Down}
Write_text(Choice,false);
Choice := Choice + PicksPerLine;
If Choice > TotalPicks then
Choice := (Choice mod PicksPerLine) + 1;
Write_Text(Choice,true);
end;
#129 : If Choice + PicksPerLine <= TotalPicks then {Mouse Down}
begin
Write_text(Choice,false);
Choice := Choice + PicksPerLine;
Write_Text(Choice,true);
end;
#200 : begin {cursor up}
Write_Text(Choice,false);
Choice := Choice - PicksPerLine;
If Choice < 1 then
begin
Choice := Choice + PicksPerline;
Choice :=
((TotalPicks div PicksPerLine)*PicksPerLine)
- PicksPerLine + 1 + Choice - 2;
If Choice + PicksPerLine <= TotalPicks then
Choice := Choice + PicksPerLine; {phew!}
end;
Write_Text(Choice,true);
end;
#128 : If Choice - PicksPerLine > 0 then {Mouse up}
begin
Write_Text(Choice,false);
Choice := Choice - PicksPerLine;
Write_Text(Choice,true);
end;
#203 : begin {cursor left}
Write_Text(Choice,False);
Choice := pred(choice);
If choice = 0 then Choice := TotalPicks;
Write_Text(Choice,true);
end;
#130 : If (pred(Choice) > 0) {mouse left}
and ( Choice mod PicksPerLine <> 1) then
begin
Write_Text(Choice,False);
Choice := pred(choice);
Write_Text(Choice,true);
end;
' ',
#205 : begin {cursor right}
Write_Text(Choice,false);
Choice := succ(Choice);
If choice > TotalPicks then Choice := 1;
Write_Text(Choice,true);
end;
#131 : If (succ(Choice) <= TotalPicks) {Mouse right}
and ( Choice mod PicksPerLine <> 0) then
begin
Write_Text(Choice,false);
Choice := succ(Choice);
Write_Text(Choice,true);
end;
#199 : begin {home key}
Write_Text(Choice,false);
Choice := 1;
Write_Text(Choice,true);
end;
#207 : begin {end key}
Write_Text(Choice,false);
Choice := TotalPicks;
Write_Text(Choice,true);
end;
#133, {Mouse enter}
#13 : begin {enter key}
Selected := true;
Errorcode := 0;
end;
#132, {Mouse Esc}
#27 : If AllowEsc then {Esc}
begin
Selected := true;
ErrorCode := 1;
end
else
begin
Write_Text(Choice,false);
Choice := TotalPicks;
Write_Text(Choice,true);
end;
#187..#196 : If Addprefix = 3 then {F1 to F10}
begin
Oldchoice := Choice;
Case Upcase(Chpk) of
#187 : If TotalPicks >= 1 then choice := 1 else choice := 0;
#188 : If TotalPicks >= 2 then choice := 2 else choice := 0;
#189 : If TotalPicks >= 3 then choice := 3 else choice := 0;
#190 : If TotalPicks >= 4 then choice := 4 else choice := 0;
#191 : If TotalPicks >= 5 then choice := 5 else choice := 0;
#192 : If TotalPicks >= 6 then choice := 6 else choice := 0;
#193 : If TotalPicks >= 7 then choice := 7 else choice := 0;
#194 : If TotalPicks >= 8 then choice := 8 else choice := 0;
#195 : If TotalPicks >= 9 then choice := 9 else choice := 0;
#196 : If TotalPicks >= 10 then choice := 10 else choice := 0;
end; {case}
If Choice = 0 then
Choice := Oldchoice
else
begin
Write_Text(Oldchoice,false);
Write_Text(Choice,true);
Selected := true;
Errorcode := 0;
end;
end;
'1'..'0': If (AddPrefix in [1,3]) then {Number or Function Prefix}
begin
If (Str_to_int(CHpk) in [1..TotalPicks]) then
begin
Write_Text(Choice,false);
Choice := Str_to_Int(CHpk);
Write_Text(Choice,true);
Selected := true;
ErrorCode := 0;
end;
end;
'A'..'Z': If AddPrefix = 2 then
If (pos(upcase(CHpk),Alphabet) in [1..TotalPicks]) then
begin
Write_Text(Choice,false);
Choice := pos(upcase(CHpk),Alphabet);
Write_Text(Choice,true);
Selected := true;
Errorcode := 0;
end;
end;
Until Selected;
end; {do}
end; {proc Process_keystrokes}
begin
GetDimensions;
CreateMenu;
Horiz_Sensitivity := 2; {two cursors left/right before mouse returns}
Process_Keystrokes;
If Window then RmWin;
end; {Main Procedure DisplayMenu}
end.